/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Model;

import Actors.Actor;
import ElementsProperties.Activable;
import Actors.HumanControlledBall;
import java.util.ConcurrentModificationException;
import java.util.Vector;

/**
 *
 * @author Snowangelic
 */
public class ActorManager implements ActorListener,InventoryListener {
    Vector<Actor> actorList;
    Actor playerBall;

    Vector<ActorManagerListener> listeners;
    Vector<PlayerBallListener> playerBallListeners;

    EnigmaModel model;

    ActorManager(EnigmaModel model){
        actorList=new Vector<Actor>();
        listeners=new Vector<ActorManagerListener>();
        playerBallListeners=new Vector<PlayerBallListener>();
        this.model=model;
    }

    public double[] getPlateImpulse(Actor a) {
        return model.getPlateImpulse(a);
    }

    public double[] getUserImpulse() {
        return model.getUserImpulse();
    }

    public void clear(){
        actorList.clear();
        playerBall=null;
    }

    void addListener(ActorManagerListener listener){
        if(!listeners.contains(listener))
            listeners.add(listener);
    }

    void addPlayerBallListener(PlayerBallListener listener){
        if(!playerBallListeners.contains(listener))
            playerBallListeners.add(listener);
    }

    public void addActor(Actor a){
        a.setManager(this);
        for(ActorManagerListener listener : listeners)
            listener.actorAdded(new ActorEvent(a));

        if(a instanceof HumanControlledBall)
            playerBall=a;
        a.addListener(this);
        actorList.add(a);
    }

    void update(long dtime){
        try{
            for (Actor actor : actorList)
                actor.update(dtime);
        }
        catch(ConcurrentModificationException e){}
    }

    public void actorMoved(ActorEvent e) {
        Actor source=e.getSource();
        for(Actor target : actorList){
            if(!source.equals(target))
                if(actorCollison(source,target)){
                    source.collidesWith(target);
                    target.collidesWith(source);
                }
        }
        if(e.getSource().equals(playerBall)){
            for(PlayerBallListener listener : playerBallListeners )
                listener.ballMoved(e);
        }
    }

    public void actorDied(ActorEvent e){
        actorList.remove(e.getSource());
        if(e.getSource().equals(playerBall)){
            playerBall=null;
            for(PlayerBallListener listener : playerBallListeners)
                listener.playerKilled(e);
        }
    }

    private boolean actorCollison(Actor source ,Actor target){
        if(distBetweenActors(source,target)<=source.getRayon()+target.getRayon())
            return true;
        else return false;
    }

    private double distBetweenActors(Actor source,Actor target){
        double xDist=source.getX()-target.getX();
        double yDist=source.getY()-target.getY();
        return Math.sqrt((xDist*xDist)+(yDist*yDist));
    }

    public void inventoryUpdated(InventoryEvent e) {
    }

    public void itemDropped(ItemDroppedEvent e) {
    }

    public void itemUsed(ItemUsedEvent e) {
        Activable item = e.getSource();
        if (playerBall != null)
            item.actOn((HumanControlledBall)playerBall);
    }

    public void actorImageChanged(ActorEvent e) {
    }
}
